package laxmysql

import (
    "errors"
    "fmt"
    "go.uber.org/zap"
    "sync"
)

// @Desc: myqsl管理
type LaxMySQLMgr struct {
    connMap map[string]*LaxMySQLConn
}
var mgrInstance *LaxMySQLMgr
var once sync.Once

func GetLaxMySQLMgr() *LaxMySQLMgr {
    once.Do(func() {
        mgrInstance = &LaxMySQLMgr{
            connMap: make(map[string]*LaxMySQLConn),
        }
    })
    return mgrInstance
}

func (mgr *LaxMySQLMgr) RegisterConn(id string, conn *LaxMySQLConn) {
    mgr.connMap[id] = conn
    zap.S().Infof("[数据库] 注册数据库id[%s]成功", id)
}

func (mgr *LaxMySQLMgr) RegisterByConfig(cfgList []LaxMySQLConfig) error {
    for _, cfg := range cfgList {
        if len(cfg.Id) < 1 {
            return errors.New(fmt.Sprintf("id valid, %s", cfg.ToString()))
        }
        conn, err := NewMySQLConn(&cfg)
        if err != nil {
            mgr.CloseAll()
            return errors.New(fmt.Sprintf("[%s] [%v] 连接失败", cfg.ToString(), err))
        }
        mgr.RegisterConn(cfg.Id, conn)
    }
    return nil
}

func (mgr *LaxMySQLMgr) CloseAll() {
    for _, v := range mgr.connMap {
        v.Close()
    }
}

func (mgr *LaxMySQLMgr) GetById(id string) *LaxMySQLConn {
    if v, ok := mgr.connMap[id]; ok {
        return v
    }
    return nil
}

type MysqlVisitCallback func (conn *LaxMySQLConn)
// @Desc: 遍历每个mysql
// @receiver mgr
// @param callback
// @param routine 是否开启协程模式
func (mgr *LaxMySQLMgr) Foreach(callback MysqlVisitCallback, routine bool) {
    var wg sync.WaitGroup
    for _, conn := range mgr.connMap {
        if routine {
            wg.Add(1)
            go func(c *LaxMySQLConn) {
                callback(c)
                wg.Done()
            }(conn)
        } else {
            callback(conn)
        }
    }
    wg.Wait()
}
